﻿#pragma once
#include "XyNet/Common/Id.h"
#include "XyNet/Common/Singleton.h"
#include "XyNet/Endpoint/RpcClient.h"
#include "XyNetTest/Protocol/cpp/Test.service.h"

namespace XyNetTest
{
	/// 聊天客户端
	class ChatClient
	{
	public:
		ChatClient(const XyNet::Id& id, const string& queries);

		/// 获取客户端
		shared_ptr<XyNet::RpcClient> getClient();

		/// 添加验证消息
		void addVerifyMessage(const string& message);
		/// 添加消息
		void addMessage(const string& message);
		/// 验证
		bool verify();

		/// 登录
		void login(const XyNet::Id& userId);
		/// 登出
		void logout();
		/// 公聊
		void publicChat(const string& message);
		/// 私聊
		void privateChat(const XyNet::Id& otherId, const string& message);

	private:
		/// 客户端id
		XyNet::Id _clientId;
		/// 客户端
		shared_ptr<XyNet::RpcClient> _client;
		/// 验证消息列表
		list<string> _verifyMessages;
		/// 消息列表
		list<string> _messages;
		/// 消息互斥量
		mutex _messageMutex;
		/// 显示日志
		bool _showLog;
	};

	//////////////////////////////////////////////////////////////////////////

	/// 测试客户端管理器
	class TestClientManager : public XyNet::Singleton<TestClientManager>
	{
	public:
		~TestClientManager();

		/// 测试
		void test(const string& query, int clientNumber);
		/// 获取测试客户端
		shared_ptr<ChatClient> getTestClient(const XyNet::Id& clientId);

	private:
		/// 创建测试客户端列表
		void createTestClients(const string& query, int clientNumber);
		/// 清除测试客户端列表
		void clearTestClients();
		/// 验证
		void verify(const string& desc);

	private:
		/// id测试客户端映射
		map<XyNet::Id, shared_ptr<ChatClient>> _idTestClientMap;
		/// id生成器
		XyNet::IdGenerator _idGenerator;
	};

	//////////////////////////////////////////////////////////////////////////

	/// 客户端用户服务
	class ClientUserServiceImpl : public ClientUserService
	{
	public:
		ClientUserServiceImpl(const XyNet::Id& id, XyNet::RpcClient* client);

		virtual void onElsewhereLogin(ElsewhereLoginMethod::Argument* argument) override;
		virtual void onOtherLogin(OtherLoginMethod::Argument* argument) override;
		virtual void onOtherLogout(OtherLogoutMethod::Argument* argument) override;

	private:
		XyNet::Id _clientId;
		XyNet::RpcClient* _client;
	};

	//////////////////////////////////////////////////////////////////////////

	/// 客户端聊天服务
	class ClientChatServiceImpl : public ClientChatService
	{
	public:
		ClientChatServiceImpl(const XyNet::Id& id);

		virtual void onPushMessage(PushMessageMethod::Argument* argument) override;
		virtual void onOtherPublicSay(OtherPublicSayMethod::Argument* argument) override;
		virtual void onOtherPrivateSay(OtherPrivateSayMethod::Argument* argument) override;

	private:
		XyNet::Id _clientId;
	};
}